#include <iostream>
#include <fstream>

#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;

int main()
{
    // 创建监听套接字，使用IPv4协议和TCP流式传输
    int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_sock < 0) 
    {
        cerr << "socket error!" << endl;
        return 1;
    }

    // 初始化服务器地址结构体
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;          // 使用IPv4地址族
    local.sin_port = htons(8888);        // 监听8888端口（主机字节序转网络字节序）
    local.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定所有可用网络接口

    // 绑定套接字与地址
    if (bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0) 
    {
        cerr << "bind error!" << endl;
        return 2;
    }

    // 开始监听，设置等待队列最大长度为5
    if (listen(listen_sock, 5) < 0) 
    {
        cerr << "listen error!" << endl;
        return 3;
    }

    // 主服务循环
    struct sockaddr peer;                // 用于存储客户端地址信息
    socklen_t len = sizeof(peer);        // 地址结构体长度
    for (;;) 
    {
        // 接受客户端连接请求，创建通信套接字
        int sock = accept(listen_sock, (struct sockaddr*)&peer, &len);
        if (sock < 0) 
        {
            cerr << "accept error!" << endl;
            continue;                   // 继续等待其他连接
        }

        // 创建子进程处理请求（父进程继续监听新连接）
        if (fork() == 0)                 // 子进程（第一层，简称父进程）
        {
            close(listen_sock);          // 子进程不需要监听，关闭监听套接字

            // 创建孙进程处理实际请求（双fork避免僵尸进程）
            if (fork() > 0)              // 父进程（第一层子进程）
            {
                exit(0);                 // 立即退出，使子进程成为孤儿进程
            }

            /* ========== 孙进程（实际处理请求）========== */
            char buffer[1024];
            recv(sock, buffer, sizeof(buffer), 0); // 读取客户端HTTP请求

            // 打印原始请求信息（用于调试）
            cout << "--------------------------http request begin--------------------------" << endl;
            cout << buffer << endl;
            cout << "---------------------------http request end---------------------------" << endl;

            // 定义网页文件路径
            #define PAGE "test.html"
            
            // 读取网页文件内容
            ifstream in(PAGE);
            if (in.is_open()) 
            {
                // 获取文件大小
                in.seekg(0, in.end);
                int len = in.tellg();
                in.seekg(0, in.beg);

                // 读取文件内容到内存
                char* file = new char[len];
                in.read(file, len);
                in.close();

                // 构建HTTP响应报文
                string status_line = "HTTP/1.1 200 OK\n";          // 状态行
                string response_header = "Content-Length: " + to_string(len) + "\n"; // 内容长度头
                string blank = "\n";                               // 空行（应使用\r\n符合HTTP标准）
                string response_text(file, len);                  // 响应正文
                string response = status_line + response_header + blank + response_text;

                // 发送响应到客户端
                send(sock, response.c_str(), response.size(), 0);
                
                delete[] file; // 释放文件内存
            }

            close(sock);     // 关闭通信套接字
            exit(0);         // 孙进程退出
        }

        // 主进程（祖父进程）处理
        close(sock);         // 主进程不需要通信套接字
        waitpid(-1, nullptr, 0); // 等待子进程退出（防止僵尸进程）
    }
    return 0;
}